'use strict';

const Controller = require('egg').Controller;
const _ = require('lodash');
const moment = require('moment');

class SmsController extends Controller {
  async list() {
    const body = this.ctx.request.body;

    const pageIndex = body.pageIndex || 1;
    const pageSize = body.pageSize || 20;

    const condition = {};
    if (body._id) {
      if (this.ctx.app.__mongoose.Types.ObjectId.isValid(body._id)) {
        condition._id = body._id;
      } else {
        condition._id = null;
      }
    }

    if (body.product_type) {
      condition.product_code = body.product_type;
    }
    if (body.campaign_id) {
      condition.campaign_id = this.ctx.app.__mongoose.Types.ObjectId(body.campaign_id);
    }

    if (body.start_time && body.end_time) {
      condition.start_send_time = {
        $gte: body.start_time,
        $lte: body.end_time,
      };
    } else {
      condition.start_send_time = {
        $lte: moment().add(1, 'hours'), // 一小时之前的
      };
    }

    if (body.status) {
      condition.status = body.status;
    }

    const skip = (pageIndex - 1) * pageSize;
    const smsinfo = await this.ctx.app.model.Sms.find(condition).skip(skip).limit(parseInt(pageSize))
      .sort({create_time: -1});
    const total = await this.ctx.app.model.Sms.count(condition);

    this.ctx.body = {
      code: 0,
      data: {
        list: smsinfo,
        total,
        pageIndex,
      },
    };
  }

  async daily() {
    const begin = new Date(moment().format('YYYY-MM-DD 00:00:00'));
    // let end = new Date(moment().add(1, 'days').format('YYYY-MM-DD 00:00:00'))
    const end = moment().add(-1, 'hours');

    const collections = await this.ctx.app.model.Sms.find({
      start_send_time: {
        $gt: begin,
        $lt: end,
      },
    });

    if (collections.length == 0) {
      return this.ctx.body = {
        code: 0,
        data: {
          total: 0,
          success_rate: '0',
          success: 0,
          failure: '0',
          unknow: 0,
        },
      };
    }

    const total = await this.ctx.app.model.Sms.count({
      start_send_time: {
        $gt: begin,
        $lt: end,
      },
    });

    const success = await this.ctx.app.model.Sms.count({
      status: '50',
      start_send_time: {
        $gt: begin,
        $lt: end,
      },
    });

    const fail = await this.ctx.app.model.Sms.count({
      status: '60',
      start_send_time: {
        $gt: begin,
        $lt: end,
      },
    });

    const unknow = await this.ctx.app.model.Sms.count({
      status: '10',
      start_send_time: {
        $gt: begin,
        $lt: end,
      },
    });


    this.ctx.body = {
      code: 0,
      data: {
        total,
        success_rate: (Math.floor((success / total) * 10000) / 100).toString() + '%',
        success,
        failure: (Math.floor((fail / total) * 10000) / 100).toString() + '%',
        unknow,
      },
    };
  }

  async template() {
    this.ctx.validate({
      product_type: 'string',
      award_type: 'string',
    });

    const body = this.ctx.request.body;

    const templates = await this.ctx.service.sms.template();

    const result = _.filter(templates, n => n.product_type === body.product_type && n.award_type === body.award_type);

    this.ctx.body = {
      code: 0,
      data: {
        list: result,
      },
    };
  }

  // todo 将卡号嵌入到短信内容中，需了解短信模版内容
  async send() {
    const ctx = this.ctx;
    try {
      this.ctx.validate({
        product_type: 'string',
        campaign_id: 'string',
        award_id: 'string',
      }, ctx.request.query);

      const body = ctx.request.query;
      let cardList = void 0;
      const awardInfo = await ctx.app.model.Award.findById(body.award_id);
      if (!awardInfo) {
        throw new Error('没有这个奖品');
      }
      if (['3'].includes(awardInfo.type)) {
        this.ctx.validate({
          card_key: 'string',
        }, ctx.request.query);
        const parts = this.ctx.multipart();
        const part = await parts();
        cardList = await ctx.service.sms.xlsxFile(part, ['券码', '兑换链接']);
      }
      const campaign = await ctx.app.model.Campaign.findById(body.campaign_id);
      if (!campaign) {
        throw new Error('没有这个活动');
      }
      // 奖品列表
      const prizeList = await ctx.app.model.Prize.find({
        campaign_id: body.campaign_id,
        award_id: body.award_id,
        status: '10',
      });
      const prizes = [];
      for(let prize of prizeList){
        prize = prize.toObject();
        let user = await ctx.app.model.User.findById(prize.user_id, {phone_number: 1});
        if(!user){
          throw new Error(`某用户信息不完整, 缺少手机号`);
        }
        prize.user = user;
        prizes.push(prize);
      }
      if (['3'].includes(awardInfo.type)) {
        if(prizes.length !== cardList.length){
          throw new Error('获奖人与卡长度不匹配');
        }
      }

      const templates = await ctx.service.sms.template();
      // 模板签名信息
      const finalTemplate = _.filter(templates, n => n.product_type === body.product_type && n.award_type === awardInfo.type);

      const doing = prizes.map((item, index) => {
        const contentMap = {award_name: item.award_name};
        if (['3'].includes(awardInfo.type)) {
          contentMap.award_code = cardList[index]['券码'];
          contentMap.go_link = cardList[index]['兑换链接'];
        }
        return async function () {
          const result = await ctx.app.sms.send({
            contentMap: contentMap,
            customerCode: 'NM',
            extData: {},
            mobile: item.user.phone_number,
            signatureId: finalTemplate[0].signatureid,
            templateId: finalTemplate[0].templateid,
          });

          return result;
        }.call(this);
      });

      const done = await Promise.all(doing);

      // 创建短信记录
      const sendSms = done.map((item, index) => {
        return async function () {
          const obj = {
            campaign_id: body.campaign_id,
            campaign_name: campaign.title,
            product_code: body.product_type,
            ref_id: prizes[index]._id,
            phone: prizes[index].user.phone_number,
            signature_id: finalTemplate[0].signatureid,
            template_id: finalTemplate[0].templateid,
            start_send_time: Date.now(),
            content: finalTemplate[0].content.replace('xxxxx', prizes[index].award_name),
            creator: {
              operator_id: this.ctx.v._id,
              realname: this.ctx.v.realname,
            },
          };
          if (['3'].includes(awardInfo.type)) {
            obj.content = obj.content.replace('xxxx', cardList[index]['券码']);
            obj.content = obj.content.replace('http//sddfggg', cardList[index]['兑换链接']);

          }

          if (item.code == '0000') { // 发送成功
            obj.status = '10';
            obj.sms_id = item.body.mtSendRecordId;
            const n = new ctx.app.model.Sms(obj);
            await n.save();
            return n;
          } // 发送失败
          obj.status = '60';
          obj.status_desc = '';
          const n = new ctx.app.model.Sms(obj);
          await n.save();
          return n;

        }.call(this);
      });

      await Promise.all(sendSms);


      // 更新奖品状态
      await ctx.app.model.Prize.updateMany({
        campaign_id: body.campaign_id,
        award_id: body.award_id,
        status: '10',
      }, {
        status: '20',
        update_time: new Date(),
      });

      this.ctx.body = {
        code: 0,
        msg: '发送成功',
      };
    } catch (e) {
      ctx.body = {
        code: -1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }
}

module.exports = SmsController;
